package portal.servicios;

import java.util.List;

import javax.ejb.EJB;
import javax.ejb.Stateless;

import org.jboss.logging.Logger;

import portal.dao.ArticuloDAO;
import portal.dao.CompraDAO;
import portal.entidades.Articulo;
import portal.entidades.Compra;
import portal.entidades.CompraEstado;
import portal.entidades.ItemCompra;
import portal.servicios.exceptions.CompraNoEncontradaException;
import portal.servicios.exceptions.EstadoCompraInvalidoException;
import portal.util.string.StringUtil;

@Stateless
public class CompraServiceBean implements CompraService {

	@EJB
	private CompraDAO compraDAO;

	@EJB
	private ArticuloDAO artDAO;
	
	@EJB
	private NotificacionAuditoriaService notificarService;
	
	private static Logger logger = Logger.getLogger(CompraServiceBean.class);

	public CompraServiceBean() {

	}

	@Override
	public Compra marcarComoEntregada(int idCompra)
			throws CompraNoEncontradaException, EstadoCompraInvalidoException {
		Compra compra = compraDAO.obtener(new Long(idCompra));
		// Verifico si existe
		if (compra == null)
			throw new CompraNoEncontradaException();
		// Verifico que se encuentre en Pendiente de Entrega
		if (!compra.getEstado().equals(CompraEstado.PENDIENTE_ENTREGA.getEstado()))
			throw new EstadoCompraInvalidoException();
		// Si existe actualizo el estado
		compra.setEstado(CompraEstado.ENTREGADO.getEstado());
		compraDAO.actualizar(compra);
		return compra;
	}

	@Override
	public List<Compra> listarMisCompras(Long id_usuario) {
		// TODO Auto-generated method stub
		return compraDAO.listarMisCompras(id_usuario);
	}

	@Override
	public List<Compra> listarCompras() {
		// TODO Auto-generated method stub
		return compraDAO.listarCompras();
	}

	@Override
	public void agregarItemCompra(Long idCompra, Long idArticulo, Double precio, Integer cantidad) {
		logger.info("######## agregarItemCompra START ########");
		logger.info("Agregando a la Compra " + StringUtil.null2String(idCompra) +
				" el articulo " + StringUtil.null2String(idArticulo) +
				" con precio " + StringUtil.null2String(precio) + 
				" por una cantidad " + StringUtil.null2String(cantidad));
		
		Articulo articulo = new Articulo();
		List<Articulo> articulos = artDAO.listarArticulos();

		// No deberian repetirse los articulos en la tablaagregar check
		// constrint
		for (Articulo articulo2 : articulos) {
			if (articulo2.getIdProducto().longValue() == idArticulo.longValue()) {
				articulo = articulo2;
			}
		}

		Compra compra = compraDAO.obtener(idCompra);
		ItemCompra itc = new ItemCompra();
		boolean flag = true;

		// La compra no puede estar vacia en esta instancia
		if (compra.getItems().size() > 0) {
			
			for (int i = 0; i < compra.getItems().size(); i++) {
				itc = compra.getItems().get(i);
				if (itc.getArticulo().getIdProducto().longValue() == idArticulo
						.longValue()) {
					
					compra.setMontoTotal(compra.getMontoTotal() + precio.doubleValue());
					itc.setCantidad(itc.getCantidad() + cantidad.intValue());
					itc.setCompra(compra);
					compraDAO.updateItemCompra(itc);
					flag = false;
				}
			}

			if (flag) {
				// Para items distintos a los que esten en la base
				compra.setMontoTotal(precio.doubleValue());
				itc = new ItemCompra();
				itc.setCantidad(cantidad.intValue());
				itc.setArticulo(articulo);
				itc.setCompra(compra);
				compraDAO.agregarItemCompra(itc);// agregar itemC
			}

		} else {
			// El primer item se inserta
			compra.setMontoTotal(precio.doubleValue());
			itc = new ItemCompra();
			itc.setCantidad(cantidad.intValue());
			itc.setArticulo(articulo);
			itc.setCompra(compra);
			compraDAO.agregarItemCompra(itc);// agregar itemC
		}
		// Informo a Monitoreo
		try {
			notificarService.enviarInformeAuditoria("Se agrego el articulo " + 
				StringUtil.null2String(idArticulo) + " a la venta nro " + StringUtil.null2String(idCompra));
			logger.info("El articulo se agrego OK!!");
		} catch (Exception e) {
			e.printStackTrace();
			logger.info("Se encontraron problemas al agregar el articulo, ERROR: " + e.getMessage());
		}
		logger.info("######## agregarItemCompra END ########");
	}

	@Override
	public void eliminarItemCompra(Long idCompra, Long idArticulo) {
		logger.info("######## eliminarItemCompra START ########");
		logger.info("Eliminando  de la Compra " + StringUtil.null2String(idCompra) +
				" el articulo " + StringUtil.null2String(idArticulo));
		
		Compra compra = compraDAO.obtener(idCompra);
		int index = 0;
		ItemCompra item = null;
		for (int i = 0; i < compra.getItems().size(); i++) {
			ItemCompra ic = compra.getItems().get(i);
			if (ic.getArticulo().getIdProducto().equals(idArticulo)) {
				index=i;
				item=ic;
				break;
			}
		}
		List<ItemCompra>items = compra.getItems();
		items.remove(index);
		compraDAO.actualizar(compra);
		compraDAO.eliminarItemCompra(item.getId());
		// Informo a Monitoreo
		try {
			notificarService.enviarInformeAuditoria("Se elimino el articulo " + 
					StringUtil.null2String(idArticulo) + " de la venta nro " + StringUtil.null2String(idCompra));
			logger.info("El articulo se elimino OK!!");
		} catch (Exception e) {
			e.printStackTrace();
			logger.info("Se encontraron problemas al eliminar el articulo, ERROR: " + e.getMessage());
		}
		logger.info("######## eliminarItemCompra END ########");
	}

	@Override
	public void checkoutCompra(Long idCompra, Double total) {
		logger.info("######## checkoutCompra START ########");
		logger.info("Realizando checkout de la Compra " + StringUtil.null2String(idCompra) +
				" por un total de " + StringUtil.null2String(total));
		
		Compra compra = compraDAO.obtener(idCompra);
		compra.setMontoTotal(total);
		compra.setEstado(CompraEstado.PENDIENTE_ENTREGA.getEstado());
		compraDAO.actualizar(compra);
		// Informo a Monitoreo
		notificarService.notificarVenta(compra);
		try {
			notificarService.enviarInformeAuditoria("Checkout de venta nro " + 
					StringUtil.null2String(idCompra) + " realizado");
			
			logger.info("checkoutCompra de la compra realizado OK!!");
		} catch (Exception e) {
			e.printStackTrace();
			logger.info("Se encontraron problemas al realizar checkout, ERROR: " + e.getMessage());
		}
		logger.info("######## checkoutCompra END ########");
	}


	@Override
	public void updateItemCompra(Long idCompra, Long idArticulo, Double cantidad) {
		Compra compra = compraDAO.obtener(idCompra);
		ItemCompra itc;

		Articulo articulo = new Articulo();
		List<Articulo> articulos = artDAO.listarArticulos();
		// No deberian repetirse los articulos en la tablaagregar check
				// constrint
		for (Articulo articulo2 : articulos) {
			if (articulo2.getIdProducto().longValue() == idArticulo.longValue()) {
				articulo = articulo2;
			}
		}
		
		// Busco y actualizo
		if (compra.getItems().size() > 0) {
			for (int i = 0; i < compra.getItems().size(); i++) {
				itc = compra.getItems().get(i);
				if (itc.getArticulo().getIdProducto().longValue() == idArticulo.longValue()) {
					itc.setCantidad(cantidad.intValue());
					itc.setArticulo(articulo);
					itc.setCompra(compra);
					compraDAO.updateItemCompra(itc);
				}
			}
		}
	}

	@Override
	public Compra crearCompra(Compra compra) {
		Compra c = compraDAO.crear1(compra);
		return c;
	}

}
